<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Node.js基础</title>
    <link rel="stylesheet" href="../css/common.css">
    <link rel="stylesheet" href="../css/html.css">
</head>
<body>
<div class="container">
    <div class="catalogue">
        <div><a href="#node_server">初识服务端</a></div>
        <div><a href="#node_fe_be">前端和服务端如何交互</a></div>
        <div><a href="#node_response">服务端如何处理并返回数据</a></div>
        <div><a href="#node_study">如何学习Node.js和后端</a></div>
        <div><a href="#node_npm">使用npm</a></div>
        <div><a href="#node_commonjs">commonjs模块化</a></div>
        <div><a href="#node_js">nodejs和前端js区别</a></div>
        <div><a href="#node_debug">debug</a></div>
        <div><a href="#node_http">nodejs处理http请求</a></div>
        <div><a href="#node_koa2">koa2 框架</a></div>
        <div><a href="#node_mongodb">mongodb</a></div>
        <div><a href="#node_login">登录实现方案与实践</a></div>

    </div>
    <div class="substance">
        <div class="one">
            <h1 id="node_server">初识服务端</h1>
            <pre>
什么是服务端:
     前端是用户可见、可操作的部分,如树枝树叶
     服务端,又称后端、server 端
     服务端为前端提供“支撑”和“营养”,如树根

服务端的职责:
     接收前端要提交的数据
     提供前端要展示的数据
     存储数据(软件公司非常看重数据,会收集各种数据)

服务端的表现形式
     这个接口,就是服务端提供的
     前端 ajax 要调用某个接口
     如 get 请求获取数据,post 请求提交数据

留言板示例:
留言板系统 - 原型图
<img alt=" " src="../image/node/1.png" width="50%" height="50%">
留言板系统 - 开发过程
     需要 Ajax 的接口:获取留言列表,提交留言
     开发前端页面,如用 Vue
     开发服务端,提供接口

留言板系统 - 前后端设计
<img alt=" " src="../image/node/2.png" width="50%" height="50%">
            </pre>
        </div>
        <div class="one">
            <h1 id="node_fe_be">前端和服务端如何交互</h1>
            <pre class="bj">
http 协议 - 介绍
     规定了客户端和服务端如何通讯
     超文本传输协议 HyperText Transfer Protocol
     是互联网世界数据通讯的标准和基石


http 协议 - 通用
     method：请求方法，如 GET POST PUT DELETE 等
     url：后端接口的地址，即前端 Ajax 请求时的地址
     状态码：接口返回的状态，如 200 302 404 500 等

http 协议 - Request
     Request Body：请求是发送给后端的数据
     Request：请求
     Request Content-type：发送数据的格式，如 json

http 协议 - Response
     Response Body：后端返回给前端的数据
     Response：返回/响应
     Response Content-type：返回数据的格式，如 json

<img alt=" " srcset="../image/node/3.png" width="50%" height="50%">
<img alt=" " srcset="../image/node/4.png" width="50%" height="50%">


一个网页需要加载的资源: css + html + js + 图片 + 视频 + 数据

不同资源可能来自不同的域名
     js css 可能来自一个独立的域名
     html 可能来自一个单独的域名
     数据可能来自一个独立的域名

一个前端页面对应不同的服务端: 数据服务 + 静态服务

            </pre>
        </div>
        <div class="one">
            <h1 id="node_response">服务端如何处理并返回数据</h1>
            <pre>
服务端如何处理并返回数据
     用 Request 获取数据,用 Response 返回数据
     定义前端请求的 url 规则 —— 路由
     读取和存储数据

前端 Ajax 时需要 url

路由是什么:服务端的入口规则 + router + 和前端的约定

路由包含什么
     定义 url 规则,如 /api/list 和 /api/create
     定义 method,如 GET/POST 等
     定义输入（Request body）和输出（Response body）格式

路由和 url
     POST /api/create 路由 —> axios.get('/api/create', {…})
     GET  /api/list   路由 —> axios.get('/api/list?a=1')
     路由是规则,url 是具体的形式

服务端能得到 Request 和 Response
     通过 Request 可获取:method url body
     也可简称为 req 和 res
     通过 Response,可设置状态码，Content-type,body

服务端拥有 Request 和 Response 即可做任何事

路由规则的实现离不开 Request
     通过 Request 可获取: method url
     先定义路由规则（method、url 规则）
     检查 method 和 url 是否符合哪个路由

回顾留言板前后端交互
     提交留言，数据存储到哪里？
     获取留言板列表，数据从哪里来？
     服务器重启或者宕机，数据会不会丢失？

数据库
     数据库是一个独立的系统,不是 nodejs 专属的
     数据库,专职做数据的存储和查询
     先不管数据库是什么,就先以为是一个JSON

先把数据库当做是 JSON

数据库基本操作: 删除 + 新增 + 修改 + 查询 + 查询条件 + 排序

            </pre>
        </div>
        <div class="one">
            <h1 id="node_study">如何学习Node.js和后端
            | <a target="_blank" href="https://www.runoob.com/nodejs/nodejs-tutorial.html">Node.js 菜鸟教程</a>
            </h1>
            <pre class="bj">
为何选择 nodejs:
     nodejs 使用npm工具包,前端工程师熟悉
     nodejs 使用JS语法,前端工程师熟悉
     nodejs 已经普及应用

如何学习 nodejs 和后端:
     善用文档和网络
     学习一门新技术的正确套路:主动,主动,再主动

nodejs 学习范围:
     koa2 框架
     nodejs 基础知识,使用npm,处理http请求
     mongodb数据库

善用文档:
     必须要学会看文档
     程序员每天都会接触新东西
     但注意,文档并不适合从0入门

善用网络搜索:
     你遇到的问题,搜索引擎上都有答案
     你遇到的问题,别人肯定早就遇到过
     不要怕麻烦,从现在开始锻炼自己的检索能力

尝试自己找出问题的原因:
     你遇到的每个错误,都会有提示信息（可能是英文的）
     软件工程已经非常成熟
     根据提示信息去 debug 或者上网查询

不做伸手党:
     等待别人答复,时间不可控
     不主动思考就求助他人,是最低效的方式
     工作了,或者面试时,没有人有责任帮助你

能力需要慢慢培养:
     自己排查错误和搜索错误,这是一种能力
     种一棵树,最好是10年之前,其次就是现在
     要从此刻开始培养和训练

学会带着问题前行:
     有些问题解决不了,只要不影响继续前行,就先不管它
     学习不是做菜,食材都备好才开始下锅
     继续前进的过程中,你会把这些问题都解决
            </pre>
        </div>
        <div class="one">
            <h1 id="node_npm">使用npm
                | <a target="_blank" href="https://www.runoob.com/nodejs/nodejs-npm.html">npm菜鸟教程</a>
            </h1>
            <pre>
使用 npm:
     使用 npm 安装软件包
     npm 是什么
     关于 package.json

npm 是什么:
     官网 https://www.npmjs.com/
     node package manager,即nodejs软件包管理者
     有几百万的软件包,源免费

软件包有何用:
     必须搭配成熟的工具和框架才能满足需求,否则将无人使用
     现代软件工程已经完善且成熟,项目不会从0开始写
     每个成熟的开发语言或者环境,都需要成熟的软件包体系

开始使用 npm:
     npm init 初始化环境
     npm 会随着 nodejs 一起被安装
     npm install lodash --save 安装 lodash

安装 nodemon:
     --save 和 --save-dev 的区别
     npm install nodemon --save-dev
     在 package.json 的中的表现

总结:
     安装和使用 npm 包，如 lodash nodemon
     npm 是什么,软件包有何作用
     package.json（scripts dependencies devDependencies）
            </pre>
        </div>
        <div class="one">
            <h1 id="node_commonjs">commonjs模块化</h1>
            <pre>
commonjs 模块化:
     commonjs 和 ES6 Module 的区别
     commonjs 语法介绍
     为何要使用模块化

回顾 ES6 Module:
     import … from …
     export … 或 export default …
     配合 webpack,用于前端开发,如Vue

commonjs 语法介绍:
     require(…)
     module.exports
     主要用于nodejs开发

require(…) 的三个层级:
     npm包,如require('lodash')
     系统自带模块,如require('http')
     自定义模块,如require('a')

commonjs 和 ES6 Module 的区别:
     commonjs 是执行时引入,动态的
     两者语法不一样
     ES6 Module 是打包时引入,静态的

为何使用模块化:
     便于多人协作开发,各写各的互不干扰
     模块拆分开,便于代码的组织和管理
     成熟的语言,都支持模块化;如 C C++ java php python Go
            </pre>
        </div>
        <div class="one">
            <h1 id="node_js">nodejs和前端js区别</h1>
            <pre>
nodejs和前端js区别:
     前端js使用浏览器提供的 Web API
     两者都使用 js 语法
     nodejs使用nodejs API

都是用 JS 语法:
     函数的定义和执行
     变量的定义和类型
     ES6 的 Class Promise 等语法

Web API:
     前端 JS 可以使用,因为在浏览器环境
     如前端网页的 DOM BOM 事件 Ajax 等
     nodejs 则无法使用,因为是 nodejs 环境

nodejs API:
     nodejs 可以使用,因为是 nodejs 环境
     如处理 http,文件操作
     前端 JS 则无法使用,因为在浏览器环境

总结
     nodejs = js 语法 + nodejs API
     前端 js = js 语法 + Web API
     同样的语法,不同的工作
            </pre>
        </div>
        <div class="one">
            <h1 id="node_debug">debug</h1>
            <pre>
inspect 调试法:
     打开 chrome,访问 chrome://inspect
     修改 scrtips,增加inspect,启动服务
     增加 debugger,重启服务,即可调试
            </pre>
        </div>
        <div class="one">
            <h1 id="node_http">nodejs处理http请求</h1>
            <h2>定义路由</h2>
            <pre>
 定义路由（模拟留言板的获取留言列表、创建留言）
 拿到req中的url和method
 测试路由（需要安装 postman）

nodejs 定义路由
     判断 method 是否符合
     从 req 中获取 url 和 method
     看 url 是否符合规则
            </pre>
            <h2>querystring</h2>
            <pre>
什么是 querystring:
     url问号?后面的都是querystring(也叫url参数)
     http://xxx.com/list.html?keyword=nba&lang=en&a=100
     &分割,key=value形式,可继续扩展

querystring:
     从url分析query参数
     获取完整url
     直接使用 nodejs 自带的 querystring
     nodejs 获取 querystring
     什么是 querystring
     论结构化与非结构化

querystring 的作用
     动态网页的基石（web1.0 —> web2.0）
     http://xxx.com/list.html?keyword=nba&lang=en

如何利用 querystring 实现动态网页
     服务端拿到 querystring
     根据不同的 querystring,返回不同的内容
     即变化querystring,就是变换内容（只要服务端支持）

            </pre>
            <h2>req和res</h2>
            <pre>
req和res:
     req即Request,res即Response是http请求的关键
     如何拿到req和res
     如何使用req和res
     nodejs如何监听http请求

获取Request Body:
     演示如何获取 Request Body
     流stream的概念
     使用 postman 测试

使用 res 返回数据
     如何返回 JSON 数据？
     使用 res设置返回的状态码,Content-type,Body
     如何返回 html 数据？
        (1)res.end(…)
        (2)Content-type: text/html
        (3)浏览器会根据 Content-type 识别出 html 格式


nodejs 启动 Web 服务:
     使用 http 模块,启动服务
     本机的 IP 127.0.0.1; 本机的域名 localhost

结构化与非结构化
     结构化的数据，易于通过程序访问和分析，如对象和数组
     非结构化的数据，不易通过程序分析，如字符串
     编程中的数据，都尽量结构化

流（stream）的表现:
     上传文件时，有进度条
     观看视频时，一遍加载一遍观看
     网速较慢时，打开网页会先显示一部分，然后继续加载

上传:
     水即上传的数据,水管即网络（带宽不确定）
     source 即客户端（前端）,dest 即服务端
     上传不仅指大文件,泛指所有的 http Request Body

下载:
     水即下载的数据,水管即网络（带宽不确定）
     source即服务端,dest即客户端（前端）
     下载不仅指大文件,泛指所有的http Response Body

浏览器能接收流(stream)数据:
     浏览器会识别到流,并持续接收信息（会有进度条）
     服务端 res.end(…),会自动以流的形式返回
     待全部接收完,再做显示或处理（视频是一段一段的播放）


服务端如何接收 流（stream）数据:
     服务端需要识别流,并接收数据
     前端使用 Ajax 提交数据 Request Body
     还要知道何时才能接收完成
            </pre>
        </div>
        <div class="one">
            <h1 id="node_koa2">koa2 框架</h1>
            <pre>
实际项目不会从0手写:
    会选择一个框架（什么是框架？后面解释）
    会借助一些工具，如 npm i lodash
    没有工具和框架的语言,将不可用于实际项目

koa2是nodejs web server 框架;
    通过 async/await 语法高效编写 web server
	官网和文档 https://koa.bootcss.com/
	中间件机制，能合理拆分业务代码

什么是框架 frame(类比Vue):
	规范流程和格式
	封装原生代码的API
	让开发人员更加关注于业务代码,提高开发效率

框架 frame和库lib的区别:
	框架关注全流程,库关注单个功能
	框架是唯一的,库可以共存
	类比 Vue 和 lodash

koa2 安装和使用:
	安装 npm install koa2 —save
	初始化 npm init
	基本使用

koa2 环境搭建:
    介绍项目的目录和文件
    使用脚手架 koa-generator 创建 koa2 项目
    在项目中新建一个路由: 新建路由文件 + 注册路由 + 新建路由

项目目录解读:	已安装的npm插件 + 入口文件 app.js +	各个目录和文件

koa2处理http请求:
    重写模拟留言板的两个路由
    如何接收数据和返回数据
    对比 koa2代码和 nodejs原生代码

如何接收和返回数据:
	querystring 和 Request body
	ctx 即 res和 req的集合
	Response body 和 Content-type

模拟留言板接口
	重写：获取留言列表
	先回顾原生 nodejs 代码写的两个接口
	重写：创建留言

koa2与nodejs代码对比
	作用1：封装原生代码的 API; 对比代码,体验框架的作用
	作用2：规范流程和格式



koa2 中间件:
    koa2 中间件
    什么是中间件？为何使用中间件？
    模拟登录验证功能

什么是中间件:	可扩展,可插拔 + 一个流程上,独立的业务模块 + 类似于工厂的流水线

为什么使用中间件
	统一使用中间件,使得各业务代码都规范标准
	拆分业务模块,使代码清晰
	扩展性好,易添加、易删除

koa2业务代码都是中间件
	所有的 app.use(…) 都是中间件
	回顾 app.js
	路由也是中间件（只不过限制了 url 规则）

模拟登录功能
	假如所有的接口（路由）都需要登录校验
	登录校验，可使用中间件来实现
	假如只有一部分接口，需要登录校验


koa2 洋葱圈模型
	每个中间件都是 async 函数
	中间件机制,是 koa2 的精髓
	中间件的运行机制,就像洋葱圈
            </pre>
        </div>
        <div class="one">
            <h1 id="node_mongodb">mongodb
            | <a target="_blank" href="https://www.runoob.com/mongodb/mongodb-tutorial.html">mongodb菜鸟教程</a>
            </h1>
            <pre>
数据库:
	数据库是一个独立的系统，和服务端语言无关
	存储数据，要用专业的数据库软件
	数据库有很多,我们选择 mongodb

mongodb 使用
	创建集合（collection）
	创建一个数据库（database）
	文档（document）的增删改查

mongodb 概念: 集合 + 文档 + bson + NoSQL + 数据库

nodejs连接mongodb:
    安装 mongodb npm 插件
	连接数据库
	操作文档

mongoose
	基于 Model 操作数据
	Schema 和 Model
	完善留言板路由的功能

mongoose 可提供规范
	以 Model 规范 Collection
	Schema 定义数据格式的规范
	规范数据操作的 API

mongodb 数据格式过于灵活
	实际项目开发时，要有数据格式的规范（重要）
	可以插入任何数据，不受限制
	特别是多人协作开发时

完善留言板功能
	定义 Schema 和 Model
	回顾现有的代码（基于 koa2 编写的）
	完善数据操作

            </pre>
        </div>
        <div class="one">
            <h1 id="node_login">登录实现方案与实践</h1>
            <pre>
为何要讲登录？
	什么 app 都会引导注册,甚至还有新人红包
	当前网络时代，流量、用户量都非常重要
	服务端必须要处理登录和用户校验

session
	session 和 cookie 的关系
	session 是什么
	session 存储用户信息

koa2 实现登录
	使用 ctx.session
	使用 npm 插件 koa-generic-session
	模拟登录


cookie 和登录校验
	服务端操作 cookie
	cookie 是什么
	cookie 如何用于登录校验
	每个域都可有一个 cookie,跨域不共享
	存储在浏览器的一段字符串,最大 5kb
	格式如 k1=v1; k2=v2; k3=v3; （可结构化）

cookie 会随 http 请求传递给服务端
	服务端可修改cookie再返回给前端;
	每次 http 请求,cookie 都会随着传递到服务端
	默认，跨域不可传递 cookie

cookie 如何用于登录校验
	请求登录接口,成功则设置 cookie,如 user=zhangsan
	前端再请求其他接口,就会带着上述 cookie
	服务端判断cookie 有无 user=zhangsan,即可验证



cookie 不能暴露用户名
	cookie 存放用户信息明文,非常危险
	上一节，cookie 中有 user=zhangsan
	解决方案：cookie 存一个用户标识,如 userId=123

session是什么
	用户信息则存储到 session 中
	cookie 存储用户标识
	session 即用户信息的存储,和 cookie 有对应关系

koa2 实现登录
	使用 ctx.session
	使用 npm 插件 koa-generic-session
	模拟登录

使用框架,不再手写原生代码
	koa2 框架中，有现成的工具 koa-generic-session
	之前 cookie session 都是纯手写，有助于学习
	对比两者,再次体会框架的作用和价值


完善登录功能:	回顾 koa2中间件的知识 + 登录功能,对接数据库 + 完善登录中间件

登录对接数据库:
	创建 Schema 和 Model
	回顾 mongdb 和 mongose

完善登录中间件
	回顾之前模拟的登录中间件
	回顾 koa2 中间件的知识



需求分析:	原型图 + 需求很重要 + 功能描述
实际工作中需求很重要:
	产品经理写需求，然后要经过各个项目角色的评审通过
	需求：描述项目最终效果的文字和图
	需求一般包括：原型图，功能描述

留言板项目
    (1)功能描述 - 注册和登录
        用户名和密码匹配，即可登录
        用户名唯一，不能重复注册
        登录成功后，跳转到首页
    (2)功能描述 - 首页
        可查看全部留言，或查看自己的留言
        非登录用户不能进入首页，登录用户可发布留言
        只能编辑和删除自己的留言，无权操作他人留言

数据库设计
	回顾 mongoose
	mongodb 创建数据库和集合
	mongoose 定义 Schema 和 Model

接口（路由）设计
	哪些接口需要登录验证？
	需要哪些接口？
	登录如何实现（跨域传递 cookie）

初始化开发环境
	规范目录和层级
	重新初始化 koa2 环境
	连接数据库

项目开发
	跨域 & 跨域传递 cookie
	前端代码介绍
	接口开发 & 前后端联调

mongodb 常见数据库和集合
	创建集合 comments ,存储留言数据
	创建数据库 comment
	常见集合 users ,存储用户

moogoose 定义 Schema 和 Model
	定义 Schema
	回顾 mongoose
	定义 Model


需要哪些接口（路由）:	登录 + 注册 + 获取留言列表 + 创建留言 + 更新 + 删除

哪些接口需要登录校验:	注册/登录不需要 + 其他都需要

登录如何实现
	但 cookie 跨域不共享
	cookie 和 session
	前后端分离的开发方式，需要设置跨域传


为何要分层
	易于扩展
	拆分模块，职责明确清晰
	看不懂没关系，后面会再次回顾

连接数据库
	连接 mongodb
	安装 mongoose
	Schema 和 Model


跨域 & 跨域传递 cookie
	服务端要允许跨域
	前后端分离，两者不一个域，默认 ajax 有跨域限制
	跨域传递 cookie （否则没法登录）
            </pre>
        </div>
    </div>
</div>
</body>
</html>